#!/usr/bin/env python3
import sys
from scapy.all import Ether, IP, UDP, Packet, bind_layers, sniff
from scapy.fields import BitField, XShortField

def get_if():
    from scapy.all import get_if_list
    for i in get_if_list():
        if "eth0" in i:
            return i
    print("Cannot find eth0 interface")
    sys.exit(1)

class SourceRoute(Packet):
    fields_desc = [BitField("bos", 0, 1),
                   BitField("port", 0, 15)]

class SourceRoutingTail(Packet):
    fields_desc = [XShortField("etherType", 0x800)]

bind_layers(Ether, SourceRoute, type=0x1234)
bind_layers(SourceRoute, SourceRoute, bos=0)
bind_layers(SourceRoute, SourceRoutingTail, bos=1)
bind_layers(SourceRoutingTail, IP)

def handle_pkt(pkt):
    print("\n=== Received Packet ===")
    if pkt.haslayer(SourceRoute):
        print("[Type] Source-Routed Packet")
    elif pkt.haslayer(IP):
        print("[Type] Normal IPv4 Packet")
    else:
        print("[Type] Unknown")
    pkt.show2()
    sys.stdout.flush()

def main():
    iface = get_if()
    print("Sniffing on %s (UDP port 4321)" % iface)
    sys.stdout.flush()
    sniff(filter="udp and port 4321", iface=iface, prn=handle_pkt)

if __name__ == '__main__':
    main()
